package org.example.Interview;

import com.alibaba.ttl.TransmittableThreadLocal;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 面试中代码示例
 * @Author chaigq
 * @Date 2020/12/1 上午7:04
 * @Version 1.0
 */
public class interviewCode {

    // 1、父子线程怎么共享数据 interitableThreadLocals
    public static void main(String[] args) throws Exception {
//        ThreadLocal threadLocal = new ThreadLocal();
//        threadLocal.set("主线程");
//        // TODO 1
//        // 普通示例
//        Thread thread = new Thread(() -> {
//            System.out.println(threadLocal.get());
//        });
//        // 实现父子线程中数据共享，子线程获取父线程本地变量
//        InheritableThreadLocal inheritableThreadLocal = new InheritableThreadLocal();
//        System.out.println("==================");
//        // 并行流示例
//        IntStream.range(1, 10).parallel().forEach(id -> {
//            System.out.println(String.format("%s-%s", id, threadLocal.get()));
//        });


//        // TODO 2
//        // 测试父子线程本地变量
//        ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
//        threadLocal.set("InheritableThreadLocal 本地变量");
//
//        Thread thread = new Thread(() -> {
//            System.out.println(String.format("Thread-%s", threadLocal.get()));
//        });
//        thread.start();
//        System.out.println("==================");
//
//        List<Integer> ids = IntStream.range(1, 10).boxed().collect(Collectors.toList());
//        ids.parallelStream().forEach(id -> {
//            System.out.println(String.format("parallelStream-%s-%s", id, threadLocal.get()));
//        });

//        // 线程池中父线程子线程数据共享
//        ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
//        // 创建线程池
//        // Java通过Executors提供四种线程池，分别为：
//        // newCachedThreadPool创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。
//        // newFixedThreadPool 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
//        // newScheduledThreadPool 创建一个定长线程池，支持定时及周期性任务执行。
//        // newSingleThreadExecutor 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
//        ExecutorService executorService = Executors.newFixedThreadPool(1);
//        // countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行
//        // countDownLatch.join()方法来等待所有子线程完成后，才继续执行
//        // CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程
//        CountDownLatch countDownLatch1 = new CountDownLatch(1);
//        CountDownLatch countDownLatch2 = new CountDownLatch(1);
//        // 线程一
//        threadLocal.set("主线程1");
//        executorService.submit(() -> {
//            System.out.println(String.format("1Thread-%s", threadLocal.get()));
//            // 线程计数减1
//            countDownLatch1.countDown();
//        });
//        countDownLatch1.await();
//        System.out.println(String.format("%s", threadLocal.get()));
//        System.out.println("-----------------------------------------");
//        // 线程二
//        threadLocal.set("主线程2");
//        executorService.submit(() -> {
//            System.out.println(String.format("2Thread-%s", threadLocal.get()));
//            countDownLatch2.countDown();
//        });
//        System.out.println(String.format("%s", threadLocal.get()));
//
//        // 关闭线程池
//        executorService.shutdown();

        // 我们的线程池会缓存使用过的线程。当线程需要被重复利用的时候，并不会再重新执行init()初始化方法，而是直接使用已经创建过的线程，
        // 所以这里的值不会二次产生变化，那么该怎么做到真正的父子线程数据传递呢

        // =============TransmittableThreadLocal 的使用案例





    }










}
